#include <ESP8266WiFi.h>
#include <List.hpp>
#include <vector>
//巴法云服务器地址默认即可
#define TCP_SERVER_ADDR "bemfa.com"
#define TCP_SERVER_PORT "8344"

///****************只需要修改的地方,有5个*****************///

//1.WIFI名称，可以用手机热点，区分大小写，不要写错
#define DEFAULT_STASSID  "chengshao"
//2.WIFI密码
#define DEFAULT_STAPSW "123465.."
//3.巴法云用户私钥，可在控制台获取,修改为自己的UID
String UID = "9e9bffb97ecf7aee48a43a44c2239c81";
//4.主题名字，可在控制台新建
String TOPIC = "temp";
//5.主题名字，可在控制台新建
String TOPIC1  = "humi";  //用于控制的主题
//4.主题名字，可在控制台新建
String TOPIC2 = "Open1";
//5.主题名字，可在控制台新建
String TOPIC3  = "Open2";  //用于控制的主题
//4.主题名字，可在控制台新建
String TOPIC4 = "weight";
//5.主题名字，可在控制台新建
String TOPIC5  = "Light";  //用于控制的主题   
//5.主题名字，可在控制台新建
String TOPIC6  = "water";  //用于控制的主题 

String TOPIC7  = "AutoSet";  //用于控制的主题 
///*********************************************///
//设置上传速率1s（1s<=upDataTime<=60s）
#define upDataTime 1*1000

//最大字节数
#define MAX_PACKETSIZE 512

      /*****************获取到的传感器数值*****************/
      //串口获得的数据,尝试使用char 发送 
      char Rxbuff[]  = "";//字符串函数
      char data1 =0;
      char data2 =0;
      char data3 =0;
      char data4 = 0;
      char data5 = 0;
      char data6 = 0;
      char data7 = 0;
      char data8 = 0;
      char data9 = 0;
      char data10 = 0;
      char data11 = 0;
      char data12 = 0;
      char data13 = 0;
      
      String Data1 , Data2 , Data3 , Data4 , Data5 , Data6 , Data7 , Data8;

//tcp客户端相关初始化，默认即可
WiFiClient TCPclient;
String TcpClient_Buff = "";
unsigned int TcpClient_BuffIndex = 0;
unsigned long TcpClient_preTick = 0;
unsigned long preHeartTick = 0;//心跳
unsigned long preTCPStartTick = 0;//连接
bool preTCPConnected = false;

List<String>list;

//相关函数初始化
//连接WIFI
void doWiFiTick();
void startSTA();

//TCP初始化连接
void doTCPClientTick();
void startTCPClient();
void sendtoTCPServer(String p);
char* SPlit(String str , char* c);
String dataSend = "" ;
/*
  *发送数据到TCP服务器
 */
void sendtoTCPServer(String p){
  
  if (!TCPclient.connected()) 
  {
    return;
  }
  TCPclient.print(p);
}


/*
  *初始化和服务器建立连接
*/
void startTCPClient(){
  if(TCPclient.connect(TCP_SERVER_ADDR, atoi(TCP_SERVER_PORT))){
    
	
	String tcpTemp="";
    tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC+"\r\n";
	  sendtoTCPServer(tcpTemp);

   tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC1+"\r\n";
   sendtoTCPServer(tcpTemp);

   tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC2+"\r\n";
   sendtoTCPServer(tcpTemp);

   tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC3+"\r\n";
   sendtoTCPServer(tcpTemp);

   tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC4+"\r\n";
   sendtoTCPServer(tcpTemp);

   tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC5+"\r\n";
   sendtoTCPServer(tcpTemp);

   tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC6+"\r\n";
   sendtoTCPServer(tcpTemp);

   tcpTemp = "cmd=1&uid="+UID+"&topic="+TOPIC7+"\r\n";
   sendtoTCPServer(tcpTemp);

   
    preTCPConnected = true;
    preHeartTick = millis();
    TCPclient.setNoDelay(true);
  }
  else{
    TCPclient.stop();
    preTCPConnected = false;
  }
  preTCPStartTick = millis();
}


/*
  *检查数据，发送数据
*/
void doTCPClientTick(){
 //检查是否断开，断开后重连
   if(WiFi.status() != WL_CONNECTED) return;

  if (!TCPclient.connected()) {//断开重连

  if(preTCPConnected == true){

    preTCPConnected = false;
    preTCPStartTick = millis();
    Serial.println();
    Serial.println("TCP Client disconnected.");
    TCPclient.stop();
  }
  else if(millis() - preTCPStartTick > 1*1000)//重新连接
    startTCPClient();
  }
  else
  {
    if(millis() - preHeartTick >= upDataTime)
    {//上传数据
      preHeartTick = millis();
      /*********************数据上传*******************/
      String upstr = "";
      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC+"&msg="+Data1+"\r\n";
      sendtoTCPServer(upstr);upstr = "";

      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC1+"&msg="+Data2+"\r\n";
      sendtoTCPServer(upstr);upstr = "";

      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC2+"&msg="+Data3+"\r\n";
      sendtoTCPServer(upstr);upstr = "";

      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC3+"&msg="+Data4+"\r\n";
      sendtoTCPServer(upstr);upstr = "";

      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC4+"&msg="+Data5+"\r\n";
      sendtoTCPServer(upstr);upstr = "";

      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC6+"&msg="+Data6+"\r\n";
      sendtoTCPServer(upstr);upstr = "";

      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC5+"&msg="+Data7+"\r\n";
      sendtoTCPServer(upstr);upstr = "";

      upstr = "cmd=2&uid="+UID+"&topic="+TOPIC7+"&msg="+Data8+"\r\n";
      sendtoTCPServer(upstr);upstr = "";
    }
  }
   TcpClient_Buff="";
   TcpClient_BuffIndex = 0;
}
void startSTA(){
  int i = 0;
  WiFi.disconnect();
  WiFi.mode(WIFI_STA);
  WiFi.begin(DEFAULT_STASSID, DEFAULT_STAPSW);
}

/**************************************************************************
                                 WIFI  
***************************************************************************/

void doWiFiTick(){
  // 开启8266的网络，连接到WIFI
  // wifi名称为：ssid指向的字符串，密码为password指向的串
  //WiFi.begin(ssid, password);
startSTA();

  // 显示正在连接到wifi
  Serial.print("\nconnecting to wifi:\n");

  // 在等待过程中，每隔1秒显示一个小点，以表示正在连接
  // 最多等待20秒，超过20秒则显示连接失败
  for (int i = 0; i < 20; i++) {
    // 检查连接状态是否已经连接上
    if (WiFi.status() == WL_CONNECTED) {
      // 显示连接成功信息, 包含从网络中获得的IP地址
      Serial.println("Wifi conntected.");
      return;
    }
    delay(1000);
    Serial.print(".");
  }
  
  Serial.print("\nConnect failed: timemout!\n");
}

// 初始化，相当于main 函数
void setup() {
  Serial.begin(115200);
  doWiFiTick();
}

void DataSet(String Data)
{
  int flag = 0;
  Data1.clear();Data2.clear();Data3.clear();Data4.clear();
  Data5.clear();Data6.clear();Data7.clear();Data8.clear();
  for(int i = 0 ; i < Data.length() ; i++)
  {
    if(Data[i] == '/')
    {
      flag++;
      i++;
    }
    switch(flag)
    {
      case 0:
      Data1 += Data[i];
      break;
      case 1:
      Data2 += Data[i];
      break;
      case 2:
      Data3 += Data[i];
      break;
      case 3:
      Data4 += Data[i];
      break;
      case 4:
      Data5 += Data[i];
      break;
      case 5:
      Data6 += Data[i];
      break;
      case 6:
      Data7 += Data[i];
      break;
      case 7:
      Data8 += Data[i];
      break;
    }
  }
}

//循环
void loop() 
{
    
  if(Serial.available())
  {
    doTCPClientTick();
    String DataStr = "";
    while (Serial.available() > 0)//循环串口是否有数据
      {
        DataStr += char(Serial.read());   //叠加数据到comdata
        delay(2); //延时2ms
      } 
    //Serial.println(DataStr);
    DataSet(DataStr);
  }
  if (TCPclient.available()) //收数据
  {
    TcpClient_Buff =TCPclient.readString();
    delay(2);
  }
  List<String>list1,list2,list3;
 
  SPlit(TcpClient_Buff , '\n' , list1);
        
  for(int i = 0;i<list1.getSize(); i++)
  {
    SPlit(list1.get(i) , '&' , list2);
  }
  for(int k = 0;k<list2.getSize(); k++)
  {
    SPlit(list2.get(k) , '=' , list3);
  }
  for(int j = 0;j<list3.getSize(); j++)
  {
    //Serial.println(list3.get(j));
    if(list3.get(j) == "AutoSet")
    {
      dataSend = dataSend + String(list3.get(j+2) + "/");
    }
    else if(list3.get(j) == "humi")
    {
      dataSend =dataSend +  String(list3.get(j+2) + "/");
    }
    else if(list3.get(j) == "Light")
    {
      dataSend = dataSend +String(list3.get(j+2) + "/");
    }
    else if(list3.get(j) == "Open1")
    {
      dataSend = dataSend + String(list3.get(j+2) + "/");
    }
    else if(list3.get(j) == "Open2")
    {
      dataSend = dataSend + String(list3.get(j+2) + "/");
    }
    else if(list3.get(j) == "temp")
    {
      dataSend = dataSend + String(list3.get(j+2) + "/");
    }
    else if(list3.get(j) == "water")
    {
      dataSend = dataSend + String(list3.get(j+2) + "/");
    }
    else if(list3.get(j) == "weight")
    {
      dataSend = dataSend + String(list3.get(j+2) + "/");
    }
  }
  Serial.print(dataSend);
  dataSend.clear();
  TcpClient_Buff.clear();
}

//自定义SPlit

void SPlit(String str , char c , List<String>&list1)
{
  String temp = "";
  String str1 = "cmd=1\n";String str2 = "cmd=2\n";
  String str3 = "&res=1";String str4 = "uid=" + UID;
  String str5 = "cmd=1";String str6 = "cmd=2";
  String str7 = "cmd=1\r\n";String str8 = "cmd=2\r\n";
  for(int i = 0; i <str.length() ; i++)
  {
    if(str.charAt(i) == c || i == str.length()-1)
    {
      if(i == str.length() -1)
      {
        temp.concat(str.charAt(i));
      }
      if(temp == "")
        continue;
      list1.add(temp);
      temp = "";
      continue;
    }
    temp.concat(str.charAt(i));//1/2/3/4/5/6/7/8
    
    if(temp == str1 || temp == str2||
      temp == str3 || temp == str4 ||
      temp == str5 || temp == str6 ||
      temp == str7 || temp == str8)
        temp.clear();
  }
}
